#ifndef __SCHEDULER__
#define __SCHEDULER__
//#include <iostream>
#include <map>
#include "Shell.h"
#include "Timer.h"
#include "SystemCalls.h"
class SystemCalls;
class Node;
class Shell1;

using namespace std;
 

class Scheduler {

public:
	~Scheduler();
	//enum ThreadState {ZOMBIE=-2,BLOCKED=-1};
	
	struct Thread_Info//this is for statistics
	{
	 int status;// -2 is for ZOMBIE and -1 for BLOCKED otherwise amount of time left to run
	 int priority;
	 double tq_createNet;
	};
	// Interface functions
public:
	//static Scheduler* getInstance(int count,int sleep_time,int quantom);
		// Creates and initialize the threads and the threadtable
	void Create();
		// Starts a simple scheduler on the created threads
	void Start();
	
	double getTimeNodeI(int NodeID);
	
	double getTime();
	
	int getStatus(int NodeID);
	
	int getMaxLengthI(int NodeID);
	
	bool isNodeInserting(int id);
	
	int* getLongestQueue();
	
	void setNodeThreads(map<int,Node*> nodes);

	void ChoosePolicy(int j);
	
	void CrashNode(int id);
	
	void ReviveNode(int id);
	
	void KillAll();
	
	void setNodesCount(int size);
		
	Scheduler(int sleep_time,int quantom,Shell1* shell,Mailer* mailer);


	// private data memebers
private:
	//static Scheduler* instance;
		// The threadstable
	void RoundRobin(int j,int n);
	void SpecialPolicy(bool* ranThreads,int n);
	void LongestQueue(int l,bool* ranThreads,int n);
	void SimpleScheduling();
	bool AllZombies();
	int checkAndSolveStarvation(bool* ranThreads);
	void  resetSystemInfo();
	int numOfRuns;
	bool scp[4];
	Mailer* myMailer;
	Shell1* myShell;
	map<int,Node*> nodeThreads;
	double total_time;
	//Thread** m_ThreadsTable;
		// The threads count
	int m_NodesCount;
		// The SleepTime for every thread
	int m_SleepTime;
	int m_Quantom;
	char m_data[80];
		// The Real Thread Table where all the info sits
	Thread_Info temp;
	Thread_Info shellInfo;
	Thread_Info mailerInfo;
	map<int,Thread_Info> m_NodesTableInfo;
	Timer timer;
};

extern int ID;
 
#endif



